#ifndef NATRIUM_CORE_KERNEL_H
#define NATRIUM_CORE_KERNEL_H

#include <future>
#include <memory>
#include <boost/noncopyable.hpp>

#include "core/event.h"
#include "core/task.h"
#include "util/concurrent_queue.h"

namespace core {
	class Kernel:
		public boost::noncopyable
	{
	public:
		typedef std::shared_ptr<Task> TaskPtr;
		typedef util::ConcurrentQueue<TaskPtr> TaskList;

		struct StopEvent {};

		Kernel();
		~Kernel();

		void add(TaskPtr task);

		void start();
		void stop();

		void operator()(const StopEvent&);
		void operator()(const Task::TaskCompleted& tc);

	private:
		void execute(TaskPtr task);
		void synchronize();

		typedef std::vector<std::future<void> > ScheduledTasks;
		typedef std::mutex Mutex;
		typedef std::condition_variable Condition;
		typedef std::lock_guard<Mutex> ScopedLock;

		TaskList mTaskList[2];
		ScheduledTasks mBackgroundTasks;
		ScheduledTasks mSyncTasks[2];

		unsigned int mReadMainList;
		unsigned int mReadSyncList;
		unsigned int mWriteMainList;
		unsigned int mWriteSyncList;

		mutable bool mRunning;
		EventChannel mChan;
		Mutex mSyncMutex;
	};
}

#endif